#ifndef __CHIP_COMMON_HAL_DEFINE__
#define __CHIP_COMMON_HAL_DEFINE__
#ifdef __cplusplus
extern "C"
{
#endif

#include "chip_select_def.h"

#define TIM0_ENUM 0
#define TIM1_ENUM 1
#define TIM4_ENUM 4

  typedef struct
  {
    uint32_t Pin; /*!< Specifies the GPIO pins to be configured.
                       This parameter can be any value of @ref GPIO_pins */

    uint32_t Mode; /*!< Specifies the operating mode for the selected pins.
                        This parameter can be a value of @ref GPIO_mode */

    uint32_t Pull; /*!< Specifies the Pull-up or Pull-Down activation for the selected pins.
                        This parameter can be a value of @ref GPIO_pull */

    uint32_t Speed; /*!< Specifies the speed for the selected pins.
                         This parameter can be a value of @ref GPIO_speed */

    uint32_t Alternate; /*!< Peripheral to be connected to the selected pins
                             This parameter can be a value of @ref GPIOEx_Alternate_function_selection */
  } GPIO_InitTypeDef;

  typedef enum
  {
    HAL_OK = 0x00U,
    HAL_ERROR = 0x01U,
    HAL_BUSY = 0x02U,
    HAL_TIMEOUT = 0x03U
  } HAL_StatusTypeDef;

  /**
   * @brief  HAL Lock structures definition
   */
  typedef enum
  {
    HAL_UNLOCKED = 0x00U,
    HAL_LOCKED = 0x01U
  } HAL_LockTypeDef;



  #define CNT_SUB_TO(x, y) \
	{                    \
		if (x > y)       \
			x--;         \
	}

#ifndef CNT_SUB_TO_ZERO
#define CNT_SUB_TO_ZERO(x) \
  if (x > 0)               \
  {                        \
    x--;                   \
  }
#endif

#ifndef LOOP_VAR
#define LOOP_VAR(x, y) \
  {                    \
    if (x < 1)         \
    {                  \
      x = y;           \
    }                  \
    else               \
    {                  \
      x--;             \
    }                  \
  }
#endif


#define LOOP_VAR_ADD(x, y) \
	{                      \
		if (x > y)         \
		{                  \
			x = 0;         \
		}                  \
		else               \
		{                  \
			x++;           \
		}                  \
	}






#ifndef HAS_MASK
#define HAS_MASK(x, y) (0 != (x & y))
#endif

  /* Exported macro ------------------------------------------------------------*/

#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */

#define HAL_MAX_DELAY 0xFFFFFFFFU

#define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) == (BIT))
#define HAL_IS_BIT_CLR(REG, BIT) (((REG) & (BIT)) == 0U)

#define __HAL_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = 0U)

#if (USE_RTOS == 1U)
/* Reserved for future use */
#error " USE_RTOS should be 0 in the current HAL release "
#else
#define __HAL_LOCK(__HANDLE__)            \
  do                                      \
  {                                       \
    if ((__HANDLE__)->Lock == HAL_LOCKED) \
    {                                     \
      return HAL_BUSY;                    \
    }                                     \
    else                                  \
    {                                     \
      (__HANDLE__)->Lock = HAL_LOCKED;    \
    }                                     \
  } while (0U)

#define __HAL_UNLOCK(__HANDLE__)       \
  do                                   \
  {                                    \
    (__HANDLE__)->Lock = HAL_UNLOCKED; \
  } while (0U)
#endif /* USE_RTOS */

  typedef enum
  {
    GPIO_PIN_RESET = 0U,
    GPIO_PIN_SET
  } GPIO_PinState;

#define GPIO_PIN_0 ((uint16_t)0x0001U)   /* Pin 0 selected    */
#define GPIO_PIN_1 ((uint16_t)0x0002U)   /* Pin 1 selected    */
#define GPIO_PIN_2 ((uint16_t)0x0004U)   /* Pin 2 selected    */
#define GPIO_PIN_3 ((uint16_t)0x0008U)   /* Pin 3 selected    */
#define GPIO_PIN_4 ((uint16_t)0x0010U)   /* Pin 4 selected    */
#define GPIO_PIN_5 ((uint16_t)0x0020U)   /* Pin 5 selected    */
#define GPIO_PIN_6 ((uint16_t)0x0040U)   /* Pin 6 selected    */
#define GPIO_PIN_7 ((uint16_t)0x0080U)   /* Pin 7 selected    */
#define GPIO_PIN_8 ((uint16_t)0x0100U)   /* Pin 8 selected    */
#define GPIO_PIN_9 ((uint16_t)0x0200U)   /* Pin 9 selected    */
#define GPIO_PIN_10 ((uint16_t)0x0400U)  /* Pin 10 selected   */
#define GPIO_PIN_11 ((uint16_t)0x0800U)  /* Pin 11 selected   */
#define GPIO_PIN_12 ((uint16_t)0x1000U)  /* Pin 12 selected   */
#define GPIO_PIN_13 ((uint16_t)0x2000U)  /* Pin 13 selected   */
#define GPIO_PIN_14 ((uint16_t)0x4000U)  /* Pin 14 selected   */
#define GPIO_PIN_15 ((uint16_t)0x8000U)  /* Pin 15 selected   */
#define GPIO_PIN_All ((uint16_t)0xFFFFU) /* All pins selected */

#define GPIO_PIN_MASK (0x0000FFFFU) /* PIN mask for assert test */

#define GPIO_MODE_INPUT MODE_INPUT                    /*!< Input Floating Mode                   */
#define GPIO_MODE_OUTPUT_PP (MODE_OUTPUT | OUTPUT_PP) /*!< Output Push Pull Mode                 */
#define GPIO_MODE_OUTPUT_OD (MODE_OUTPUT | OUTPUT_OD) /*!< Output Open Drain Mode                */
#define GPIO_MODE_AF_PP (MODE_AF | OUTPUT_PP)         /*!< Alternate Function Push Pull Mode     */
#define GPIO_MODE_AF_OD (MODE_AF | OUTPUT_OD)         /*!< Alternate Function Open Drain Mode    */

#define GPIO_MODE_ANALOG MODE_ANALOG /*!< Analog Mode  */

#define GPIO_MODE_IT_RISING (MODE_INPUT | EXTI_IT | TRIGGER_RISING)                           /*!< External Interrupt Mode with Rising edge trigger detection          */
#define GPIO_MODE_IT_FALLING (MODE_INPUT | EXTI_IT | TRIGGER_FALLING)                         /*!< External Interrupt Mode with Falling edge trigger detection         */
#define GPIO_MODE_IT_RISING_FALLING (MODE_INPUT | EXTI_IT | TRIGGER_RISING | TRIGGER_FALLING) /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */

#define GPIO_MODE_EVT_RISING (MODE_INPUT | EXTI_EVT | TRIGGER_RISING)   /*!< External Event Mode with Rising edge trigger detection             */
#define GPIO_MODE_EVT_FALLING (MODE_INPUT | EXTI_EVT | TRIGGER_FALLING) /*!< External Event Mode with Falling edge trigger detection            */
#define GPIO_MODE_EVT_RISING_FALLING (MODE_INPUT | EXTI_EVT | TRIGGER_RISING | TRIGGER_FALLING)

#define GPIO_SPEED_FREQ_LOW (0x00000000U)    /*!< range up to 2 MHz, please refer to the product datasheet */
#define GPIO_SPEED_FREQ_MEDIUM (0x00000001U) /*!< range  4 MHz to 10 MHz, please refer to the product datasheet */
#define GPIO_SPEED_FREQ_HIGH (0x00000003U)   /*!< range 10 MHz to 50 MHz, please refer to the product datasheet */
                                             /**
                                              * @}
                                              */

  /** @defgroup GPIO_pull GPIO pull
   * @brief GPIO Pull-Up or Pull-Down Activation
   * @{
   */
#define GPIO_NOPULL (0x00000000U)   /*!< No Pull-up or Pull-down activation  */
#define GPIO_PULLUP (0x00000001U)   /*!< Pull-up activation                  */
#define GPIO_PULLDOWN (0x00000002U) /*!< Pull-down activation                */

#define GPIO_MODE_Pos 0U
#define GPIO_MODE (0x3UL << GPIO_MODE_Pos)
#define MODE_INPUT (0x0UL << GPIO_MODE_Pos)
#define MODE_OUTPUT (0x1UL << GPIO_MODE_Pos)
#define MODE_AF (0x2UL << GPIO_MODE_Pos)
#define MODE_ANALOG (0x3UL << GPIO_MODE_Pos)
#define OUTPUT_TYPE_Pos 4U
#define OUTPUT_TYPE (0x1UL << OUTPUT_TYPE_Pos)
#define OUTPUT_PP (0x0UL << OUTPUT_TYPE_Pos)
#define OUTPUT_OD (0x1UL << OUTPUT_TYPE_Pos)
#define EXTI_MODE_Pos 16U
#define EXTI_MODE (0x3UL << EXTI_MODE_Pos)
#define EXTI_IT (0x1UL << EXTI_MODE_Pos)
#define EXTI_EVT (0x2UL << EXTI_MODE_Pos)
#define TRIGGER_MODE_Pos 20U
#define TRIGGER_MODE (0x7UL << TRIGGER_MODE_Pos)
#define TRIGGER_RISING (0x1UL << TRIGGER_MODE_Pos)
#define TRIGGER_FALLING (0x2UL << TRIGGER_MODE_Pos)
/**
 * @}
 */

/** @addtogroup GPIO_Private_Macros GPIO Private Macros
 * @{
 */
#define IS_GPIO_PIN_ACTION(ACTION) (((ACTION) == GPIO_PIN_RESET) || ((ACTION) == GPIO_PIN_SET))

#define IS_GPIO_PIN(__PIN__) (((((uint32_t)__PIN__) & GPIO_PIN_MASK) != 0x00U) && \
                              ((((uint32_t)__PIN__) & ~GPIO_PIN_MASK) == 0x00U))

#define IS_GPIO_MODE(__MODE__) (((__MODE__) == GPIO_MODE_INPUT) ||              \
                                ((__MODE__) == GPIO_MODE_OUTPUT_PP) ||          \
                                ((__MODE__) == GPIO_MODE_OUTPUT_OD) ||          \
                                ((__MODE__) == GPIO_MODE_AF_PP) ||              \
                                ((__MODE__) == GPIO_MODE_AF_OD) ||              \
                                ((__MODE__) == GPIO_MODE_IT_RISING) ||          \
                                ((__MODE__) == GPIO_MODE_IT_FALLING) ||         \
                                ((__MODE__) == GPIO_MODE_IT_RISING_FALLING) ||  \
                                ((__MODE__) == GPIO_MODE_EVT_RISING) ||         \
                                ((__MODE__) == GPIO_MODE_EVT_FALLING) ||        \
                                ((__MODE__) == GPIO_MODE_EVT_RISING_FALLING) || \
                                ((__MODE__) == GPIO_MODE_ANALOG))

#define IS_GPIO_SPEED(__SPEED__) (((__SPEED__) == GPIO_SPEED_FREQ_LOW) ||    \
                                  ((__SPEED__) == GPIO_SPEED_FREQ_MEDIUM) || \
                                  ((__SPEED__) == GPIO_SPEED_FREQ_HIGH))

#define IS_GPIO_PULL(__PULL__) (((__PULL__) == GPIO_NOPULL) || \
                                ((__PULL__) == GPIO_PULLUP) || \
                                ((__PULL__) == GPIO_PULLDOWN))

  typedef enum
  {
    GPIO_MD_IN_NOPULL = 0x00,     /*! gpio input no-pull */
    GPIO_MD_IN_UP = 0x01,         /*! gpio input pull-up */
    GPIO_MD_IN_DOWN = 0x02,       /*! gpio input pull-down */
    GPIO_MD_OUT_PP = 0x03,        /*! gpio output push-pull */
    GPIO_MD_OUT_OD_NOPULL = 0x04, /*! gpio output open-drain no-pull */
    GPIO_MD_OUT_OD_UP = 0x05,     /*! gpio output open-drain pull-up */
    GPIO_MD_AF_NOPULL = 0x06,     /*! gpio alternate function no-pull */
    GPIO_MD_AF_UP = 0x07,         /*! gpio alternate function pull-up */
    GPIO_MD_AF_DOWN = 0x08,       /*! gpio alternate function pull-down */
    GPIO_MD_AF_PP = 0x09,         /*! gpio alternate function push-pull */
    PIO_MD_AF_OD_NOPULL = 0x0A,  /*! gpio alternate function open-drain no-pull */
    GPIO_MD_AF_OD_UP = 0x0B,      /*! gpio alternate function open-drain pull-up */
    GPIO_MD_AN = 0x0C,            /*! gpio analog */
  } TYPE_ENUM_GPIO_ALL_MODE;

#ifdef __cplusplus
}
#endif
#endif
